package com.example.teamwork.impl;

import com.example.teamwork.Enum.UserStatusEnum;
import com.example.teamwork.Enum.UserTypeEnum;
import com.example.teamwork.Shrio.Bean.ActiveUser;
import com.example.teamwork.Shrio.Exception.ErrorCodeEnum;
import com.example.teamwork.Shrio.Exception.ServiceException;
import com.example.teamwork.Shrio.Token.JWTToken;
import com.example.teamwork.Shrio.Util.JWTUtil;
import com.example.teamwork.converter.MenuConverter;
import com.example.teamwork.converter.UserConverter;
import com.example.teamwork.informationGet.*;
import com.example.teamwork.mapper.*;
import com.example.teamwork.pojo.*;
import com.example.teamwork.service.PartService;
import com.example.teamwork.service.UserService;
import com.example.teamwork.utils.test1;
import com.example.teamwork.utils.MenuTreeBuilder;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 〈用户模块〉<br>
 * 〈〉
 * @author  SongPeng
 * @date  2021/10/19 14:25
 * @version 1.0
 */

@Service
@Mapper
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private UserConverter userConverter;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private PartService partService;
    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private PartMapper partMapper;

    @Override
    public User getUserByname(String name) {
        User t = new User();
        t.setName(name);
        return userMapper.selectOne(t);
    }

    /**
     * 更新用户禁用状态
     * @param userId
     * @param userStatus
     */
    @Override
    public void updateStatus(Long userId, Boolean userStatus) {
        User dbUser = userMapper.selectByPrimaryKey(userId);
        if(dbUser==null){
            throw new ServiceException("要更新状态的用户不存在");
        }
        ActiveUser activeUser= (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(dbUser.getUserId().equals(activeUser.getUser().getUserId())){
            throw new ServiceException(ErrorCodeEnum.DoNotAllowToDisableTheCurrentUser);
        }else {
            User t = new User();
            t.setUserId(userId);
            t.setUserStatus(userStatus? UserStatusEnum.DISABLE.getStatusCode() :
                    UserStatusEnum.AVAILABLE.getStatusCode());
            // 根据主键更新属性不为null的值
            userMapper.updateByPrimaryKeySelective(t);
        }
    }
    /**
     * 重置用户密码
     * @param userId
     */
    @Override
    public void resetPassword(Long userId) {
        User dbUser = userMapper.selectByPrimaryKey(userId);
        if(dbUser==null){
            throw new ServiceException("要重置密码的用户不存在");
        }
        ActiveUser activeUser= (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(dbUser.getUserId().equals(activeUser.getUser().getUserId())){
            throw new ServiceException(ErrorCodeEnum.DoNotAllowToDisableTheCurrentUser);
        }else {
            User t = new User();
            t.setUserId(userId);
            String salt=UUID.randomUUID().toString().substring(0,32);
            t.setSalt(salt);
            t.setPassword(test1.md5Encryption("111111", salt));
            // 根据主键更新属性不为null的值
            userMapper.updateByPrimaryKeySelective(t);
        }
    }

    @Override
    public void editAvater(String avater, Long userId) {
        User dbUser =userMapper.selectByPrimaryKey(userId);
        if(dbUser==null){
            throw  new ServiceException("修改头像的用户已下线");
        }
        dbUser.setAvater(avater);
        userMapper.updateByPrimaryKeySelective(dbUser);
    }
    /**
     *  当前登录用户更改自身信息
     * */
    @Override
    public void editSelf(User user) {

        user.setModifiedTime(new Date());
        //根据主键更新属性不为null的值
        userMapper.updateByPrimaryKeySelective(user);


    }
    /**
     * 用户修改密码
     * */
    @Override
    public void editPassword(String password, String newPassword) {
        ActiveUser activeUser= (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        String oldPassword=activeUser.getUser().getPassword();
        String salt=activeUser.getUser().getSalt();
        String password1=test1.md5Encryption(password,salt);
        User user=new User();
        if(oldPassword.equals(password1)){
            user.setPassword(test1.md5Encryption(newPassword,salt));
            user.setUserId(activeUser.getUser().getUserId());
            userMapper.updateByPrimaryKeySelective(user);
        }else{
            throw  new ServiceException("用户密码输入错误");
        }
    }



    /**
     * 添加用户
     * @param userVO
     */
    @Transactional
    @Override
    public void add(UserVO userVO) {
        String name = userVO.getName();
        Long departmentId = userVO.getPartId();
        Example o = new Example(User.class);
        o.createCriteria().andEqualTo("name",name);
        //根据Condition(对象属性)条件进行查询总数
        int i = userMapper.selectCountByExample(o);
        if(i!=0){
            throw new ServiceException("该用户名已被占用");
        }
        Part department = partMapper.selectByPrimaryKey(departmentId);
        if(department==null){
            throw new ServiceException("该部门不存在");
        }
        User user = new User();
        BeanUtils.copyProperties(userVO,user);
        String salt=UUID.randomUUID().toString().substring(0,32);
        user.setPassword(test1.md5Encryption("123456", salt));
        user.setModifiedTime(new Date());
        user.setCreateTime(new Date());
        user.setSalt(salt);
        user.setUserType(UserTypeEnum.SYSTEM_USER.getTypeCode());//添加的用户默认是普通用户
        user.setUserStatus(UserStatusEnum.AVAILABLE.getStatusCode());//添加的用户默认启用
        userMapper.insert(user);
    }
    /**
     * 更新
     * @param userId
     * @param userVO
     */
    @Transactional
    @Override
    public void update(Long userId,UserEditVO userVO) {
        User dbUser = userMapper.selectByPrimaryKey(userId);
        @NotBlank(message = "用户名不能为空") String name = userVO.getName();
        @NotNull(message = "部门不能为空") Long departmentId = userVO.getPartId();
        if(dbUser==null){
            throw new ServiceException("要删除的用户不存在");
        }
        Part part = partMapper.selectByPrimaryKey(departmentId);
        if(part==null){
            throw new ServiceException("该部门不存在");
        }
        Example o = new Example(User.class);
        o.createCriteria().andEqualTo("name",name);
        List<User> users = userMapper.selectByExample(o);
        if(!CollectionUtils.isEmpty(users)){
            if(!users.get(0).getUserId().equals(userId)){
                throw new ServiceException("该用户名已被占用");
            }
        }
        User user = new User();
        BeanUtils.copyProperties(userVO,user);
        user.setModifiedTime(new Date());
        user.setUserId(dbUser.getUserId());
        //根据主键更新属性不为null的值
        userMapper.updateByPrimaryKeySelective(user);
    }


    /**
     * 删除用户
     * @param userId 用户ID
     */
    @Transactional
    @Override
    public void deleteById(Long userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();

        if(user==null){
            throw new ServiceException("要删除的用户不存在");
        }

        if(user.getUserId().equals(activeUser.getUser().getUserId())){
            throw new ServiceException("不能删除当前登入用户");
        }

        userMapper.deleteByPrimaryKey(userId);
        //删除对应[用户-角色]记录
        userRoleMapper.deleteByExample(userId);
    }
    /**
     * 用户详情
     *
     * @return UserInfoGet
     */
    @Override
    public UserInfoGet info() {
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
//        System.out.println(activeUser);
        UserInfoGet userInfoGet = new UserInfoGet();
        userInfoGet.setUserName(activeUser.getUser().getUserName());
        List<String> roleNames = activeUser.getRoles().stream().map(Role::getRoleName).collect(Collectors.toList());
        userInfoGet.setRoles(roleNames);
        userInfoGet.setUrl(activeUser.getUrls());
        userInfoGet.setAvater(activeUser.getUser().getAvater());
        userInfoGet.setName(activeUser.getUser().getName()) ;
        userInfoGet.setPerms(activeUser.getPermissions());
        userInfoGet.setIsAdmin(activeUser.getUser().getUserType()== UserTypeEnum.SYSTEM_ADMIN.getTypeCode());
        userInfoGet.setUserAge(activeUser.getUser().getUserAge());
        userInfoGet.setUserPhone(activeUser.getUser().getUserPhone());
        PartVO dept = partService.edit(activeUser.getUser().getPartId());
        if(dept!=null){
            userInfoGet.setDepartment(dept.getPartName());
        }
        return userInfoGet;
    }
    /**
     * 编辑
     * @param userId
     * @return
     */
    @Transactional
    @Override
    public UserEditVO edit(Long userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if(user==null){
            throw new ServiceException("要编辑的用户不存在");
        }
        UserEditVO userEditVO = new UserEditVO();
        BeanUtils.copyProperties(user,userEditVO);
        Part part = partMapper.selectByPrimaryKey(user.getPartId());
        if(part!=null){
            userEditVO.setPartId(part.getPartId());
        }
        return userEditVO;
    }


    /**
     * 用户角色
     *
     * */
    @Override
    public List<Role> getRolesByUserId(Long userid) {
        User dbUser = userMapper.selectByPrimaryKey(userid);
        if(dbUser==null){
            throw new ServiceException("该用户不存在");
        }
        List<Role> roles=new ArrayList<>();
        Long t=dbUser.getUserId();
        List<UserRole> userRoleList = userRoleMapper.getUserRoles(t);
        List<Long> rids=new ArrayList<>();
        if(!CollectionUtils.isEmpty(userRoleList)){
            for (UserRole userRole : userRoleList) {
                rids.add(userRole.getRoleId());
            }
            if(!CollectionUtils.isEmpty(rids)){
                for (Long rid : rids) {
                    Role role = roleMapper.selectByPrimaryKey(rid);
                    if(role!=null){
                        roles.add(role);
                    }
                }
            }
        }
        return roles;
    }
    /*
     * 用户权限菜单
     * */
    @Override
    public List<Permission> findPermissionsByRoles(List<Role> roles) {
        Set<Long> prepermissionIds=new HashSet<>();
        List<Permission> permissions=new ArrayList<>();
        if(!CollectionUtils.isEmpty(roles)){
            Set<Long> permissionIds=new HashSet<>();//存放用户的菜单id
            List<RolePermission> rolePermissions;
            for (Role role : roles) {
                Set<Long> nextpermissionIds=new HashSet<>();
                //根据角色ID查询权限ID
                rolePermissions= rolePermissionMapper.selectByRoleId(role.getRoleId());
                if(!CollectionUtils.isEmpty(rolePermissions)){
                    for (RolePermission rolePermission : rolePermissions) {
                        nextpermissionIds.add(rolePermission.getPermissionId());
                    }
                }
                if(nextpermissionIds.size()<=prepermissionIds.size()){
                    permissionIds=prepermissionIds;
                }else{
                    permissionIds=nextpermissionIds;
                }
                prepermissionIds=nextpermissionIds;
            }
            if(!CollectionUtils.isEmpty(permissionIds)){
                for (Long permissionId : permissionIds) {
                    //该用户所有的菜单
                    Permission permission = permissionMapper.selectByPrimaryKey(permissionId);
                    if(permission!=null){
                        permissions.add(permission);
                    }
                }
            }
        }
        return permissions;
    }
    @Override
    public String login(String name, String password) {
        String token;
        User user = getUserByname(name);
        if (user != null) {
            String salt = user.getSalt();
            //秘钥为盐
            String target = test1.md5Encryption(password, salt);
            //生成Token
            token = JWTUtil.sign(name, target);
            JWTToken jwtToken = new JWTToken(token);
            try {
                SecurityUtils.getSubject().login(jwtToken);
            } catch (AuthenticationException e) {
                throw new ServiceException(e.getMessage());
            }
        } else {
            throw new ServiceException(ErrorCodeEnum.USER_ACCOUNT_NOT_FOUND);
        }
        return token;
    }
    /**
     * 获取登录用户的菜单
     * @return
     */
    @Override
    public List<PermissionNodeVO> findPermission() {
        List<Permission> permissions=null;
        List<PermissionNodeVO> permissionNodeVOS=new ArrayList<>();
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        if(activeUser.getUser().getUserType()==UserTypeEnum.SYSTEM_ADMIN.getTypeCode()){
            //超级管理员
            permissions= permissionMapper.selectAll();
        }else if(activeUser.getUser().getUserType()== UserTypeEnum.SYSTEM_USER.getTypeCode()){
            //普通系统用户
            permissions= activeUser.getPermissionList();
        }
        if(!CollectionUtils.isEmpty(permissions)){
            permissionNodeVOS= MenuConverter.converterToMenuNodeVO(permissions);
        }
        //构建树形菜单
        return MenuTreeBuilder.build(permissionNodeVOS);
    }

    /**
     * 用户列表
     * @param userVO
     * @return
     */
    @Override
    public PageVO<UserVO> findUserList(Integer pageNum,Integer pageSize,UserVO userVO) {
        //已经拥有的
        PageHelper.startPage(pageNum,pageSize);
        Example o = new Example(User.class);
        String username = userVO.getUserName();
        Long departmentId = userVO.getPartId();
        Integer sex = userVO.getUserSex();
        Example.Criteria criteria = o.createCriteria();
        if(username!=null&&!"".equals(username)){
            criteria.andLike("userName","%"+username+"%");
        }
        if(sex!=null){
            criteria.andEqualTo("userSex",sex);
        }
        if(departmentId!=null){
            criteria.andEqualTo("partId",departmentId);
        }
        criteria.andNotEqualTo("userStatus",0);
        List<User> userList = userMapper.selectByExample(o);
        PageInfo<User> info=new PageInfo<>(userList);
        List<UserVO> userVOS = userConverter.converterToUserVOList(userList);
        return new PageVO<>(info.getTotal(),userVOS);
    }


    /**
     * 分配角色
     * @param userId 用户id
     * @param rids 角色数组
     */
    @Override
    @Transactional
    public void assignRoles(Long userId, Long[] rids) {
        //删除之前用户的所有角色
        User user = userMapper.selectByPrimaryKey(userId);
        if(user==null){
            throw new ServiceException("用户不存在");
        }
        //删除之前分配的
        userRoleMapper.deleteByExample(user.getUserId());
        //增加现在分配的
        if(rids.length>0){
            for (Long rid : rids) {
                Role role = roleMapper.selectByPrimaryKey(rid);
                if(role==null){
                    throw new ServiceException("roleId="+rid+",该角色不存在");
                }
                //判断角色状态
                if(role.getRoleStatus()==0){
                    throw new ServiceException("roleName="+role.getRoleName()+",该角色已禁用");
                }
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRole.setRoleId(rid);
                userRoleMapper.insert(userRole);
            }
        }
    }

    @Override
    public List<Long> roles(Long id) {

        User user = userMapper.selectByPrimaryKey(id);
        if(user==null){
            throw new ServiceException("该用户不存在");
        }
        List<UserRole> userRoleList = userRoleMapper.getUserRoles(user.getUserId());
        List<Long> roleIds=new ArrayList<>();
        if(!CollectionUtils.isEmpty(userRoleList)){
            for (UserRole userRole : userRoleList) {
                Role role = roleMapper.selectByPrimaryKey(userRole.getRoleId());
                if(role!=null){
                    roleIds.add(role.getRoleId());
                }
            }
        }
        return roleIds;
    }
}

